package main

import (
	"bufio"
	"distributed_db/client"
	"distributed_db/monitor/raft"
	"distributed_db/rsc"
	"distributed_db/utils"
	"fmt"
	"math/rand"
	"os"
	"strings"
)

const (
	TestID   = "test_rpc"
	TestIP   = "localhost"
	UserName = "root"
	PassWord = "130900zhang"
)

func GeneratePorts(n int) []string {
	s := make([]string, n)
	mp := make(map[int]bool)
	cnt := 0
	for cnt < n {
		port := rand.Int()%1000 + 1200
		if _, exist := mp[port]; !exist {
			s[cnt] = fmt.Sprintf("%d", port)
			mp[port] = true
			cnt++
		}
	}
	return s
}

func GenerateTCP(ports []string) []string {
	s := make([]string, len(ports))
	for i := 0; i < len(ports); i++ {
		s[i] = "127.0.0.1:" + ports[i]
	}
	return s
}

func GeneratePeers(ports []string) []*utils.ClientEnd {
	clients := make([]*utils.ClientEnd, len(ports))
	for i := 0; i < len(ports); i++ {
		clients[i] = utils.MakeEnd("127.0.0.1:" + ports[i])
	}
	return clients
}

func simulation(s_num int) {
	// 启动 RegionServer
	rsc.NewRSC(TestID, TestIP, "9081", UserName, PassWord, "db1")
	rsc.NewRSC(TestID, TestIP, "9082", UserName, PassWord, "db2")
	rsc.NewRSC(TestID, TestIP, "9083", UserName, PassWord, "db3")
	rsc.NewRSC(TestID, TestIP, "9084", UserName, PassWord, "db4")
	rsc.NewRSC(TestID, TestIP, "9085", UserName, PassWord, "db5")
	// 启动 master 集群
	ports := GeneratePorts(s_num)
	server_end := GenerateTCP(ports)
	servers := make([]*raft.Server, s_num)
	for i := 0; i < s_num; i++ {
		servers[i] = raft.MakeServer(GeneratePeers(ports), ports[i], i)
		servers[i].StartRaftService()
	}
	// 启动客户端
	c, _ := client.NewClient(server_end)
	// 启动命令行服务
	reader := bufio.NewReader(os.Stdin)
	for {
		fmt.Print("请输入语句: ")
		input, err := reader.ReadString('\n')
		// 去掉结尾的换行符
		input = strings.TrimSpace(input)
		if err != nil {
			fmt.Println("读取输入时出错:", err)
			return
		}
		if input == "quit" {
			fmt.Println("退出程序")
			return
		} else if input == "show" {
			for table, rs := range c.RegionServers {
				fmt.Printf("%s: %v\n", table, rs)
			}
		} else if input == "help" {
			fmt.Println("help: 显示帮助信息")
			fmt.Println("quit: 退出程序")
			fmt.Println("show: 展示table与region_server信息")
			fmt.Println("select cols from table_name where cond")
			fmt.Println("insert into table_name (cols) values (values)")
			fmt.Println("delete from table_name where cond")
			fmt.Println("create table table_name (cols)")
			fmt.Println("drop table table_name")
			fmt.Println("keepalive [table_names]")
		} else {
			switch strings.Split(input, " ")[0] {
			case "select":
				resp, err := c.Select(input)
				if err != nil {
					fmt.Println("执行查询时出错:", err)
				} else {
					for k, v := range resp.Data {
						fmt.Printf("%d: %s\n", k, v)
					}
				}
			case "insert":
				resp, err := c.InsertData(input)
				if err != nil {
					fmt.Println("执行插入时出错:", err)
				} else {
					fmt.Println(resp)
				}
			case "delete":
				resp, err := c.DeleteData(input)
				if err != nil {
					fmt.Println("执行删除时出错:", err)
				} else {
					fmt.Println(resp)
				}
			case "create":
				resp, err := c.CreateTable(input)
				if err != nil {
					fmt.Println("执行创建表时出错:", err)
				} else {
					fmt.Println(resp)
				}
			case "drop":
				resp, err := c.DropTable(input)
				if err != nil {
					fmt.Println("执行删除表时出错:", err)
				} else {
					fmt.Println(resp)
				}
			case "keepalive":
				resp, err := c.Keep(input)
				if err != nil {
					fmt.Println("执行更新缓存时出错:", err)
				} else {
					fmt.Println(resp)
				}
			default:
				fmt.Println("未知命令:", input)
			}
		}
	}

}

func main() {
	simulation(5)
}
